package com.je.meta.service.project;

import com.je.common.base.DynaBean;
import com.je.common.base.service.MetaService;
import com.je.common.base.spring.SpringContextHolder;
import com.je.common.base.util.ProjectContextHolder;
import com.je.common.base.util.TreeUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.model.dd.DicInfoVo;
import com.je.meta.rpc.project.ProjectOrgRpcService;
import com.je.meta.rpc.project.ProjectUserRpcService;
import com.je.servicecomb.RpcSchemaFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("projectOrgUserTreeService")
public class ProjectOrgUserTreeService {

    private static final Logger log = LoggerFactory.getLogger(ProjectOrgUserTreeService.class);
    @Autowired
    private MetaService metaService;

    public JSONTreeNode buildTree(DicInfoVo dicInfoVo) {
        JSONTreeNode root = TreeUtil.buildRootNode();
        if (ProjectContextHolder.getProject() == null) {
            return root;
        }

        DynaBean orgMappingBean = metaService.selectOne("JE_RBAC_PROJECTORGMAPPING",
                ConditionsWrapper.builder().eq("PROJECTORGMAPPING_ENABLE_CODE", "1"));
        if (orgMappingBean == null) {
            return root;
        }

        String orgProductCode = orgMappingBean.getStr("PROJECTORGMAPPING_PRODUCT_CODE");
        String orgTableCode = orgMappingBean.getStr("PROJECTORGMAPPING_TABLE_CODE");
        String orgPkFieldCode = orgMappingBean.getStr("PROJECTORGMAPPING_PKFIELD_CODE");
        String orgNameFieldCode = orgMappingBean.getStr("PROJECTORGMAPPING_NAMEFIELD_CODE");
        String orgCodeFieldCode = orgMappingBean.getStr("PROJECTORGMAPPING_CODEFIELD_CODE");
        String orgParentIdFieldCode = orgMappingBean.getStr("PROJECTORGMAPPING_PARENTFIELD_CODE");
        String orgOrderFieldCode = orgMappingBean.getStr("PROJECTORGMAPPING_ORDERFIELD_CODE");
        String orgProjectIdFieldCode = orgMappingBean.getStr("PROJECTORGMAPPING_PROJECTPKFIELD_CODE");
        String orgProjectGlSql = orgMappingBean.getStr("PROJECTORGMAPPING_GLSQL");

        ProjectOrgRpcService projectOrgRpcService;
        if ("meta".equals(orgProductCode)) {
            projectOrgRpcService = SpringContextHolder.getBean(ProjectOrgRpcService.class);
        } else {
            projectOrgRpcService = RpcSchemaFactory.getRemoteProvierClazz(orgProductCode, "projectOrgRpcService", ProjectOrgRpcService.class);
        }

        List<DynaBean> deptBeanList = projectOrgRpcService.findProjectOrgWithOrder(orgTableCode, orgProjectIdFieldCode,
                ProjectContextHolder.getProject().getId(), orgOrderFieldCode, orgProjectGlSql);
        if (deptBeanList == null || deptBeanList.isEmpty()) {
            return root;
        }

        DynaBean userMappingBean = metaService.selectOne("JE_RBAC_PROJECTUSERMAPPING",
                ConditionsWrapper.builder().eq("PROJECTUSERMAPPING_ENABLE_CODE", "1"));
        if (userMappingBean == null) {
            return root;
        }

        String userProductCode = userMappingBean.getStr("PROJECTUSERMAPPING_PRODUCT_CODE");
        String userTableCode = userMappingBean.getStr("PROJECTUSERMAPPING_TABLE_CODE");
        String userTableGlSql = userMappingBean.getStr("PROJECTUSERMAPPING_GLSQL");
        String userIdFieldCode = userMappingBean.getStr("PROJECTUSERMAPPING_PKFIELD_CODE");
        String userNameFieldCode = userMappingBean.getStr("PROJECTUSERMAPPING_NAMEFIELD_CODE");
        String userCodeFieldCode = userMappingBean.getStr("PROJECTUSERMAPPING_CODEFIELD_CODE");
        String userProjectIdFieldCode = userMappingBean.getStr("PROJECTUSERMAPPING_PROJECTPKFIELD_CODE");
        String userOrgIdFieldCode = userMappingBean.getStr("PROJECTUSERMAPPING_DEPTIDFIELD_CODE");
        String systemDeptAccountUserIdFieldCode = userMappingBean.getStr("PROJECTUSERMAPPING_SYSUSERPKFIELD_CODE");

        ProjectUserRpcService projectUserRpcService;
        if ("meta".equals(userProductCode)) {
            projectUserRpcService = SpringContextHolder.getBean(ProjectUserRpcService.class);
        } else {
            projectUserRpcService = RpcSchemaFactory.getRemoteProvierClazz(userProductCode, "projectUserRpcService", ProjectUserRpcService.class);
        }

        List<DynaBean> userBeanList = projectUserRpcService.findProjectUserWithOrder(userTableCode, userProjectIdFieldCode,
                ProjectContextHolder.getProject().getId(), "SY_CREATETIME", userTableGlSql);

        JSONTreeNode eachNode;
        String rootId = "";
        for (DynaBean dynaBean : deptBeanList) {
            if ("ROOT".equalsIgnoreCase(dynaBean.getStr("SY_NODETYPE"))) {
                rootId = dynaBean.getStr(orgPkFieldCode);
            }
        }

        for (DynaBean dynaBean : deptBeanList) {
            if (!rootId.equals(dynaBean.getStr(orgParentIdFieldCode))) {
                continue;
            }
            eachNode = buildDeptNode(root, dynaBean, userBeanList, orgPkFieldCode, orgNameFieldCode, orgCodeFieldCode,
                    userIdFieldCode, userNameFieldCode, userCodeFieldCode, userOrgIdFieldCode, systemDeptAccountUserIdFieldCode);
            recursiveBuildDeptTree(eachNode, deptBeanList, userBeanList,
                    orgPkFieldCode, orgNameFieldCode, orgCodeFieldCode, orgParentIdFieldCode,
                    userIdFieldCode, userNameFieldCode, userCodeFieldCode, userOrgIdFieldCode, systemDeptAccountUserIdFieldCode);
            root.getChildren().add(eachNode);
        }

        return root;
    }

    private void recursiveBuildDeptTree(JSONTreeNode parentNode, List<DynaBean> deptBeanList,
                                        List<DynaBean> userBeanList, String orgPkFieldCode,
                                        String orgNameFieldCode, String orgCodeFieldCode, String orgParentIdFieldCode,
                                        String userPkFieldCode, String userNameFieldCode, String userCodeFieldCode,
                                        String userOrgIdFieldCode, String userDeptAccountIdFieldCode) {
        JSONTreeNode childNode;
        for (DynaBean dynaBean : deptBeanList) {
            if (!parentNode.getId().equals(dynaBean.getStr(orgParentIdFieldCode))) {
                continue;
            }
            childNode = buildDeptNode(parentNode, dynaBean, userBeanList,
                    orgPkFieldCode, orgNameFieldCode, orgCodeFieldCode, userPkFieldCode,
                    userNameFieldCode, userCodeFieldCode, userOrgIdFieldCode, userDeptAccountIdFieldCode);
            recursiveBuildDeptTree(childNode, deptBeanList, userBeanList,
                    orgPkFieldCode, orgNameFieldCode, orgCodeFieldCode, orgParentIdFieldCode,
                    userPkFieldCode, userNameFieldCode, userCodeFieldCode, userOrgIdFieldCode, userDeptAccountIdFieldCode);
            parentNode.getChildren().add(childNode);
        }
    }

    private JSONTreeNode buildDeptNode(JSONTreeNode parentNode, DynaBean deptBean,
                                       List<DynaBean> userBeanList, String orgPkFieldCode,
                                       String orgNameFieldCode, String orgCodeFieldCode,
                                       String userPkFieldCode, String userNameFieldCode,
                                       String userCodeFieldCode, String userOrgIdFieldCode,
                                       String userDeptAccountIdFieldCode) {
        JSONTreeNode deptNode = TreeUtil.buildTreeNode(deptBean.getStr(orgPkFieldCode),
                deptBean.getStr(orgNameFieldCode),
                deptBean.getStr(orgCodeFieldCode),
                "",
                "dept",
                "",
                parentNode.getId());
        deptNode.setBean(deptBean.getValues());
        for (DynaBean userBean : userBeanList) {
            if (userBean.getStr(userOrgIdFieldCode).equals(deptBean.getStr(orgPkFieldCode))) {
                deptNode.getChildren().add(buildUserNode(deptNode, userBean, userPkFieldCode, userNameFieldCode, userCodeFieldCode, userDeptAccountIdFieldCode));
            }
        }

        return deptNode;
    }

    private JSONTreeNode buildUserNode(JSONTreeNode parentNode, DynaBean userBean, String userPkFieldCode,
                                       String userNameFieldCode, String userCodeFieldCode, String userDeptAccountIdFieldCode) {
        JSONTreeNode userNode = TreeUtil.buildTreeNode(userBean.getStr(userPkFieldCode),
                userBean.getStr(userNameFieldCode),
                userBean.getStr(userCodeFieldCode),
                userBean.getStr(userDeptAccountIdFieldCode),
                "user",
                "",
                parentNode.getId());
        userNode.setBean(userBean.getValues());
        return userNode;
    }

}
